1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : roleplay/classes/class.roleset.inc.php
5 : - Modulgruppe: Roleplay
6 : - Beschreibung: Klasse zum Erstellen eines Rollenset-Objekts inkl. der enthaltenen Rollen
7 : und Bereitstellen von zugehörigen Funktionen.
8 : - Version: 0.7, 26/11/06
9 : - Autor(en): Clemens Weiß <clemens.weiss@mni.fh-giessen.de>
10 : +---------------------------------------------------------------------------+
11 : This program is free software; you can redistribute it and/or
12 : modify it under the terms of the GNU General Public License
13 : as published by the Free Software Foundation; either version 2
14 : of the License, or any later version.
15 : +---------------------------------------------------------------------------+
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 : +--------------------------------------------------------------------------*/
24 : /**
25 : * Klasse zum Erstellen eines Rollenset-Objekts inkl. der enthaltenen Rollen
26 : * und Bereitstellen von zugehörigen Funktionen.
27 : * @package eStudy.Roleplay
28 : * @version 0.7, 26/11/06
29 : * @author Clemens Weiß <clemens.weiss@mni.fh-giessen.de>
30 : */
31 : require_once (PATH_TO_ROOT."roleplay/classes/class.role.inc.php");
32 : require_once (PATH_TO_ROOT."roleplay/classes/class.rolesetlist.inc.php");
33 : require_once (PATH_TO_ROOT."roleplay/classes/class.userrolemanagement.inc.php");
34 : class RoleSet {
35 : /**
36 : * ID der Vorlage
37 : * @var integer
38 : * @access private
39 : */
40 : var $ID;
41 : /**
42 : * Name der Vorlage
43 : * @var string
44 : * @access private
45 : */
46 : var $name;
47 : /**
48 : * Beschreibung des Rollen-Sets
49 : * @var string
50 : * @access private
51 : */
52 : var $description;
53 : /**
54 : * Kurs-ID der Vorlage (0 bei globaler Vorlage)
55 : * @var integer
56 : * @access private
57 : */
58 : var $courseID;
59 : /**
60 : * Autor der Vorlage
61 : * @var string
62 : * @access private
63 : */
64 : var $author;
65 : /**
66 : * Timestamp der Erstellung der Vorlage
67 : * @var integer
68 : * @access private
69 : */
70 : var $date;
71 : /**
72 : * Gibt an, ob das Set in dem Kurs verwendet wird
73 : * @var boolean
74 : * @access private
75 : */
76 : var $isActive;
77 : /**
78 : * In der Vorlage definierte Rollen
79 : * @var array
80 : * @access private
81 : */
82 : var $roles;
83 : /**
84 : * Konstruktor.
85 : * Erstellt das Vorlagen-Objekt mit den Daten der per ID bestimmten Vorlage.
86 : * Wird eine ungültige ID (oder 0) übergeben, wird eine neue Vorlage
87 : * erstellt.
88 : *
89 : * @access public
90 : * @param int $setID ID der Vorlage oder 0 für neue Vorlage
91 : */
92 : function RoleSet($setID) {
93 0 : global $db, $settings;
94 0 : $dbp = $settings["dbPrefix"];
95 0 : $newTemplate = false;
96 0 : if (is_integer($setID) && $setID > 0) {
97 0 : $templateData = $db->get_row("SELECT * FROM {$dbp}rolesets WHERE id='$setID'");
98 0 : if ($db->num_rows) {
99 0 : $this->ID = (int)$templateData->id;
100 0 : $this->name = $templateData->name;
101 0 : $this->description = $templateData->description;
102 0 : $this->courseID = (int)$templateData->course_id;
103 0 : $this->author = $templateData->author;
104 0 : $this->date = (int)$templateData->date;
105 0 : $this->isActive = (bool)$templateData->is_active;
106 0 : $this->roles = array();
107 0 : $roleIDs = $db->get_col("SELECT id FROM {$dbp}roles WHERE set_id='$setID' ORDER BY name");
108 0 : if (count($roleIDs)) {
109 0 : foreach($roleIDs as $roleID) {
110 0 : $this->roles[(int)$roleID] = new Role((int)$roleID);
111 0 : }
112 0 : }
113 0 : } else {
114 0 : $newTemplate = true;
115 : }
116 0 : } else {
117 0 : $newTemplate = true;
118 : }
119 0 : if ($newTemplate) {
120 0 : $this->setDefaultValues();
121 0 : }
122 0 : }
123 : /**
124 : * Versucht, die im übergebenen Array vorhandenen Daten anhand der
125 : * assoziativen Array-Indizes als neue Rollen-Set-Daten abzuspeichern. Dabei
126 : * kann es sich zum Beispiel um das $_POST-Array handeln. Es werden dabei
127 : * entweder alle oder keine Daten gespeichert. Sind einige der Daten
128 : * fehlerhaft, wird ein String mit Fehlermeldungen zurückgeliefert, sonst
129 : * der boolsche Wert true.
130 : *
131 : * @access public
132 : * @param array $data Assoziatives Array mit den neuen Werten
133 : * @return mixed String mit Fehlermeldungen oder true bei Erfolg
134 : */
135 : function setData($data) {
136 0 : $errors = "";
137 0 : if (($result = $this->validateName($data["name"])) !== true) {
138 0 : $errors.= $result."\n";
139 0 : }
140 0 : if (($result = $this->validateAuthor($data["author"])) !== true) {
141 0 : $errors.= $result."\n";
142 0 : }
143 0 : if (empty($errors)) {
144 0 : if (!$this->setName($data["name"])) {
145 0 : return "Bezeichnung konnte nicht gespeichert werden.";
146 : }
147 0 : if (!$this->setAuthor($data["author"])) {
148 0 : return "Autor konnte nicht gespeichert werden.";
149 : }
150 0 : if (!$this->setDescription($data["description"])) {
151 0 : return "Beschreibung konnte nicht gespeichert werden.";
152 : }
153 0 : return true;
154 : }
155 0 : return trim($errors);
156 : }
157 : /**
158 : * Erstellt den grundlegenden Datenbankeintrag für das Rollen-Set. Gesetzt
159 : * werden Kurs-ID, Datum und Autor, die anderen Felder werden mit ihren
160 : * Standardwerten belegt.
161 : *
162 : * @access private
163 : * @return boolean Erfolgswert
164 : */
165 : function createSet() {
166 0 : global $db, $settings;
167 0 : $dbp = $settings["dbPrefix"];
168 0 : $db->query("INSERT INTO {$dbp}rolesets (course_id, author, date) VALUES ('$this->courseID', '".Data::toMysql($this->author) ."', '$this->date')");
169 0 : if ($db->rows_affected) {
170 0 : $this->ID = $db->insert_id;
171 0 : return true;
172 : }
173 0 : return false;
174 : }
175 : /**
176 : * Löscht dieses Rollen-Set und alle darin definierten Rollen. Alle
177 : * Eigenschaften dieses Objekts werden auf Standardwerte gesetzt, so dass
178 : * damit gleich ein neues Set erzeugt werden kann.
179 : *
180 : * @access public
181 : * @return boolean Erfolgswert
182 : */
183 : function deleteSet() {
184 0 : global $db, $settings;
185 0 : $dbp = $settings["dbPrefix"];
186 0 : $db->query("DELETE FROM {$dbp}rolesets WHERE id='$this->ID'");
187 0 : if (!$db->rows_affected) {
188 0 : return false;
189 : }
190 0 : $error = false;
191 0 : foreach($this->roles as $role) {
192 0 : if (!$role->deleteRole()) {
193 0 : $error = true;
194 0 : }
195 0 : }
196 0 : if ($error) {
197 0 : return false;
198 : }
199 0 : $this->setDefaultValues();
200 0 : return true;
201 : }
202 : /**
203 : * Setzt Standardwerte für dieses Objekt, speichert die Änderungen aber
204 : * nicht in der Datenbank.
205 : *
206 : * @access private
207 : * @return void
208 : */
209 : function setDefaultValues() {
210 0 : $this->ID = 0;
211 0 : $this->name = "";
212 0 : $this->description = "";
213 0 : $this->courseID = $_SESSION["course"];
214 0 : $this->author = $_SESSION["Vorname"]." ".$_SESSION["Nachname"];
215 0 : $this->date = time();
216 0 : $this->isActive = true;
217 0 : $this->roles = array();
218 0 : }
219 : /**
220 : * Zeigt ein Formular zum Bearbeiten des Rollen-Sets an (Name und Autor).
221 : * Wird der Funktion kein Array mit den anzuzeigenden Daten (z.B. $_POST-
222 : * Array) übergeben, werden die Daten des aktuellen Sets angezeigt.
223 : * Es erfolgt keine Validierung und Speicherung dieser Daten, dazu kann die
224 : * Methode setData() verwendet werden.
225 : *
226 : * @access public
227 : * @param array $data Assoziatives Array der im Formular anzuzeigenden Daten
228 : * @return void
229 : */
230 : function showEditForm($data = null) {
231 0 : if (isset($data["name"])) $name = $data["name"];
232 0 : else $name = $this->name;
233 0 : if (isset($data["author"])) $author = $data["author"];
234 0 : else $author = $this->author;
235 0 : if (isset($data["description"])) $desc = $data["description"];
236 0 : else $desc = $this->description;
237 0 : echo "<form action=\"".PATH_TO_ROOT.SCRIPT_NAME."\" method=\"post\">\n";
238 0 : echo "<p class='pForm'><input type=\"hidden\" name=\"ID\" id=\"ID\" value=\"{$this->ID}\" /></p>\n";
239 0 : echo "<table class='tableBorder'>\n";
240 0 : if ($this->ID > 0) {
241 0 : Output::echoTableHead("Rollen-Set bearbeiten", 3);
242 0 : } else {
243 0 : Output::echoTableHead("Neues Rollen-Set erstellen", 3);
244 : }
245 0 : echo "<tr>"."<td><label for=\"name\">Bezeichnung</label></td>"."<td><p class='pForm'><input type=\"text\" name=\"name\" id=\"name\" value=\"".Data::toHTML($name) ."\" maxlength=\"255\" /></p></td>"."<td>";
246 0 : Utilities::help(0);
247 0 : echo "</td></tr>\n";
248 0 : echo "<tr>"."<td><label for=\"author\">Autor</label></td>"."<td><p class='pForm'><input type=\"text\" name=\"author\" id=\"author\" value=\"".Data::toHTML($author) ."\" maxlength=\"255\" /></p></td>"."<td>";
249 0 : Utilities::help(0);
250 0 : echo "</td></tr>\n";
251 0 : echo "<tr>"."<td><label for=\"description\">Beschreibung</label></td>"."<td><p class='pForm'><textarea name=\"description\" id=\"description\" rows=\"5\" cols=\"50\">".Data::toHTML($desc) ."</textarea></p></td>"."<td>";
252 0 : Utilities::help(0);
253 0 : echo "</td></tr>\n";
254 0 : Output::echoDialogBottom(array("okButton" => "Speichern", "cancelButton" => ""), 3);
255 0 : echo "</table>\n</form>\n";
256 0 : }
257 : /**
258 : * Gibt eine Tabelle mit den in diesem Set definierten Rollen inkl. Links
259 : * zum Bearbeiten etc. aus.
260 : *
261 : * @access public
262 : * @return void
263 : */
264 : function listRoles() {
265 0 : echo "<table class='contentTable'>\n";
266 0 : Output::echoTableHead("Im Set »".Data::toHTML($this->name) ."« definierte Rollen", 3);
267 0 : echo "<tr><th>Name</th>"."<th>Aktionen</th></tr>\n";
268 0 : if (count($this->roles)) {
269 0 : foreach($this->roles as $role) {
270 0 : echo "<tr><td>".Data::toHTML($role->getName()) ."</td>"."<td>"."<a href='".PATH_TO_ROOT.SCRIPT_NAME."?action=editRole&setID=".$role->getSetID() ."&ID=".$role->getID() ."'>".Output::getIcon("icon_edit", "Rolle bearbeiten") ."</a>"."<a href='".PATH_TO_ROOT.SCRIPT_NAME."?action=deleteRole&setID=".$role->getSetID() ."&ID=".$role->getID() ."'>".Output::getIcon("icon_muell", "Rolle löschen") ."</a>"."</td></tr>\n";
271 0 : }
272 0 : } else {
273 0 : echo "<tr><td colspan='3'>Es wurden noch keine Rollen definiert.</td></tr>\n";
274 : }
275 0 : echo "</table>";
276 0 : }
277 : /**
278 : * Erstellt eine identische Kopie des Rollen-Sets inkl. der zugehörigen
279 : * Rollen für den angegebenen Kurs.
280 : *
281 : * @access public
282 : * @param int $courseID ID des Kurses, zu dem die Kopie gehören soll
283 : * @return mixed ID der neu erzeugten Kopie oder false bei Fehler
284 : */
285 : function copySet($courseID) {
286 0 : global $db, $settings;
287 0 : $dbp = $settings["dbPrefix"];
288 0 : $copy = new RoleSet(0);
289 0 : if (!$copy->setCourseID((int)$courseID) || $copy->validateName($this->name) !== true || !$copy->setName($this->name) || !$copy->setAuthor($this->author) || !$copy->setDescription($this->description)) {
290 0 : if ($copy->getID() > 0) {
291 0 : $copy->deleteSet();
292 0 : }
293 0 : return false;
294 : }
295 0 : foreach($this->roles as $role) {
296 0 : if (!$role->copyRole($copy->getID())) {
297 0 : $copy->deleteSet();
298 0 : return false;
299 : }
300 0 : }
301 0 : $db->query("UPDATE {$dbp}rolesets SET source_id='$this->ID' WHERE id='".$copy->getID() ."'");
302 0 : return $copy->getID();
303 : }
304 : /**
305 : * Gibt die ID der Vorlage zurück.
306 : *
307 : * @access public
308 : * @return int ID der Vorlage
309 : */
310 : function getID() {
311 0 : return $this->ID;
312 : }
313 : /**
314 : * Gibt den Namen der Vorlage zurück.
315 : *
316 : * @access public
317 : * @return string Name der Vorlage
318 : */
319 : function getName() {
320 0 : return $this->name;
321 : }
322 : /**
323 : * Überprüft die übergebene Bezeichnung auf Gültigkeit.
324 : *
325 : * @access public
326 : * @param string $name Der zu überprüfende String
327 : * @return mixed String mit Fehlerangabe oder true bei Erfolg
328 : */
329 : function validateName($name) {
330 0 : global $db, $settings;
331 0 : $dbp = $settings["dbPrefix"];
332 0 : $name = trim(Data::gpcUnescape($name));
333 0 : if (empty($name)) return "Die Bezeichnung wurde nicht angegeben.";
334 0 : if (!preg_match("/^[a-zäöüßÄÖÜ0-9\/\-_ \(\)&'\"\.,]+$/i", $name)) return "Die Bezeichnung enthält ungültige Zeichen.";
335 0 : if (strlen($name) > 255) return "Die Bezeichnung ist zu lang.";
336 0 : if ($this->ID == 0 && $db->get_var("SELECT COUNT(*) FROM {$dbp}rolesets WHERE name='".Data::toMysql($name, false) ."' AND course_id='$this->courseID'") > 0) return "Ein Set mit dieser Bezeichnung ist bereits vorhanden.";
337 0 : return true;
338 : }
339 : /**
340 : * Speichert den übergebenen String als neue Bezeichnung dieses Rollen-Sets.
341 : * Der String sollte vorher mit der Methode validateName() validiert worden
342 : * sein!
343 : *
344 : * @access public
345 : * @param string $name Zu speichernde Bezeichnung
346 : * @return boolean Erfolgswert
347 : */
348 : function setName($name) {
349 0 : global $db, $settings;
350 0 : $dbp = $settings["dbPrefix"];
351 0 : $name = trim($name);
352 0 : if ($this->name == Data::gpcUnescape($name)) {
353 0 : return true;
354 : }
355 0 : if ($this->ID == 0) {
356 0 : if (!$this->createSet()) {
357 0 : return false;
358 : }
359 0 : }
360 0 : $db->query("UPDATE {$dbp}rolesets SET name='".Data::toMysql($name) ."' WHERE id='$this->ID'");
361 0 : if ($db->rows_affected) {
362 0 : $this->name = Data::gpcUnescape($name);
363 0 : return true;
364 : }
365 0 : return false;
366 : }
367 : /**
368 : * Gibt die Beschreibung des Rollen-Sets zurück.
369 : *
370 : * @access public
371 : * @return string Beschreibung des Sets
372 : */
373 : function getDescription() {
374 0 : return $this->description;
375 : }
376 : /**
377 : * Speichert den übergebenen String als neue Beschreibung dieses Rollen-Sets.
378 : *
379 : * @access public
380 : * @param string $desc Zu speichernde Beschreibung
381 : * @return boolean Erfolgswert
382 : */
383 : function setDescription($desc) {
384 0 : global $db, $settings;
385 0 : $dbp = $settings["dbPrefix"];
386 0 : $desc = trim($desc);
387 0 : if ($this->description == Data::gpcUnescape($desc)) {
388 0 : return true;
389 : }
390 0 : if ($this->ID == 0) {
391 0 : if (!$this->createSet()) {
392 0 : return false;
393 : }
394 0 : }
395 0 : $db->query("UPDATE {$dbp}rolesets SET description='".Data::toMysql($desc) ."' WHERE id='$this->ID'");
396 0 : if ($db->rows_affected) {
397 0 : $this->description = Data::gpcUnescape($desc);
398 0 : return true;
399 : }
400 0 : return false;
401 : }
402 : /**
403 : * Gibt die Kurs-ID der Vorlage zurück.
404 : *
405 : * @access public
406 : * @return int Kurs-ID der Vorlage
407 : */
408 : function getCourseID() {
409 0 : return $this->courseID;
410 : }
411 : /**
412 : * Speichert den übergebenen Integer als neue Kurs-ID dieses Rollen-Sets.
413 : *
414 : * @access public
415 : * @param integer $courseID Zu speichernde Kurs-ID
416 : * @return boolean Erfolgswert
417 : */
418 : function setCourseID($courseID) {
419 0 : global $db, $settings;
420 0 : $dbp = $settings["dbPrefix"];
421 0 : if ($this->courseID == $courseID) {
422 0 : return true;
423 : }
424 0 : if (!is_integer($courseID) || $courseID < 0) {
425 0 : return false;
426 : }
427 0 : if ($this->ID == 0) {
428 0 : if (!$this->createSet()) {
429 0 : return false;
430 : }
431 0 : }
432 0 : $db->query("UPDATE {$dbp}rolesets SET course_id='$courseID' WHERE id='$this->ID'");
433 0 : if ($db->rows_affected) {
434 0 : $this->courseID = $courseID;
435 0 : return true;
436 : }
437 0 : return false;
438 : }
439 : /**
440 : * Gibt den Autor der Vorlage zurück.
441 : *
442 : * @access public
443 : * @return string Autor der Vorlage
444 : */
445 : function getAuthor() {
446 0 : return $this->author;
447 : }
448 : /**
449 : * Überprüft den übergebenen Namen auf Gültigkeit.
450 : *
451 : * @access public
452 : * @param string $author Der zu überprüfende String
453 : * @return mixed String mit Fehlerangabe oder true bei Erfolg
454 : */
455 : function validateAuthor($author) {
456 0 : $author = trim(Data::gpcUnescape($author));
457 0 : if (empty($author)) return "Der Autor wurde nicht angegeben.";
458 0 : if (!preg_match("/^[a-zäöüßÄÖÜ\- ']*$/i", $author)) return "Der Autorname enthält ungültige Zeichen.";
459 0 : if (strlen($author) > 255) return "Der Autorname ist zu lang.";
460 0 : return true;
461 : }
462 : /**
463 : * Speichert den übergebenen String als neuen Autor dieses Rollen-Sets.
464 : * Der String sollte vorher mit der Methode validateAuthor() validiert
465 : * worden sein!
466 : *
467 : * @access public
468 : * @param string $author Zu speichernder Autorname
469 : * @return boolean Erfolgswert
470 : */
471 : function setAuthor($author) {
472 0 : global $db, $settings;
473 0 : $dbp = $settings["dbPrefix"];
474 0 : $author = trim($author);
475 0 : if ($this->author == Data::gpcUnescape($author)) {
476 0 : return true;
477 : }
478 0 : if ($this->ID == 0) {
479 0 : if (!$this->createSet()) {
480 0 : return false;
481 : }
482 0 : }
483 0 : $db->query("UPDATE {$dbp}rolesets SET author='".Data::toMysql($author) ."' WHERE id='$this->ID'");
484 0 : if ($db->rows_affected) {
485 0 : $this->author = Data::gpcUnescape($author);
486 0 : return true;
487 : }
488 0 : return false;
489 : }
490 : /**
491 : * Gibt zurück, ob das Set im Kurs gerade verwendet wird.
492 : *
493 : * @access public
494 : * @return bool true, wenn das Set verwendet wird, sonst false
495 : */
496 : function isActive() {
497 0 : return $this->isActive;
498 : }
499 : /**
500 : * Speichert, ob dieses Set in dem Kurs verwendet wird.
501 : *
502 : * @access public
503 : * @param bool $isActive true, wenn das Set verwendet wird, sonst false
504 : * @return bool Erfolgswert
505 : */
506 : function setActive($isActive) {
507 0 : global $db, $settings;
508 0 : $dbp = $settings["dbPrefix"];
509 0 : if (!is_bool($isActive)) {
510 0 : return false;
511 : }
512 0 : if ($this->isActive == $isActive) {
513 0 : return true;
514 : }
515 0 : if ($this->ID == 0) {
516 0 : if (!$this->createSet()) {
517 0 : return false;
518 : }
519 0 : }
520 0 : $db->query("UPDATE {$dbp}rolesets SET is_active='".(int)$isActive."' WHERE id='$this->ID'");
521 0 : if ($db->rows_affected) {
522 0 : $this->isActive = $isActive;
523 0 : if (!$isActive && $this->courseID > 0) {
524 0 : if (count($this->roles) > 0) {
525 : // alle Rollen dieses Sets für User inaktiv setzen
526 0 : $db->query("UPDATE {$dbp}user_roles SET is_active=0 WHERE role_id IN (".implode(", ", array_keys($this->roles)) .")");
527 0 : }
528 0 : }
529 0 : if (RoleSetList::roleplayForced($this->courseID)) {
530 : // alle Kursmitglieder durchgehen und eine andere Rolle aktiv setzen, wenn nötig
531 0 : $users = Course::getParticipants($this->courseID, "all", "user.Nachname, user.Vorname");
532 0 : if (is_array($users) && !empty($users)) {
533 0 : $urm = new UserRoleManagement($this->courseID);
534 0 : foreach($users as $user) {
535 0 : $roles = $urm->getRolesOfUser((int)$user->userid);
536 0 : $active = false;
537 0 : $lastRoleID = 0;
538 0 : foreach($roles as $roleID => $role) {
539 0 : if ($role["isActive"]) {
540 0 : $active = true;
541 0 : break;
542 : }
543 0 : $lastRoleID = $roleID;
544 0 : }
545 0 : if (!$active && $lastRoleID > 0) {
546 0 : $urm->setActiveUserRole((int)$user->userid, $lastRoleID);
547 0 : }
548 0 : }
549 0 : }
550 0 : }
551 0 : return true;
552 : }
553 0 : return false;
554 : }
555 : /**
556 : * Gibt den Timestamp der Erstellung der Vorlage zurück.
557 : *
558 : * @access public
559 : * @return int Timestamp der Vorlage
560 : */
561 : function getDate() {
562 0 : return $this->date;
563 : }
564 : /**
565 : * Gibt die Rollenobjekte der Vorlage zurück.
566 : *
567 : * @access public
568 : * @return array Rollen der Vorlage
569 : */
570 : function getRoles() {
571 0 : return $this->roles;
572 : }
573 : }
|